
console.log("//-----------basic.ts output-------------")
/*1、命名的方法*/
function add(x,y){    
    return x+y;
}

/*2、匿名方法*/
var myAdd = function(x,y) { 
    return x+y;
}

/*在 TypeScript 中，也兼容上面两种定义方式，但是，既然我们用的是 TypeScript，
那么肯定要强于本来的定义方式。*/
/*1、类型化方法*/
function add1(x:number, y:number):number{    
    return x+y;
}
var myAdd2 = function(x:number, y:number):number {
    return x+y;
}

/*为参数和返回值定义好类型，有助于智能感知和程序逻辑。*/

/*2、函数类型变量*/
/*在上面第一点，myAdd 变量的类型我们没有指定，完整的写法如下：*/
var myAdd3: (x:number, y:number)=>number = function(x:number, y:number):number { 
    return x+y; 
}

/*当然类型参数的命名可以不相同的*/
var myAdd4: (baseValue:number, increment:number)=>number = function(x:number, y:number):number {
    return x+y;
}

/*3、可选参数*/
function buildName(firstName: string, lastName?: string):string{    
    if(lastName){        
        return firstName + " " + lastName;    
    }    
    else{        
        return firstName;    
    }
}
/*在参数名后面，冒号前面添加一个问号，则表明该参数是可选的。*/

/*4、默认参数*/
function buildName2(firstName: string, lastName = "Smith"):string {    
    return firstName + " " + lastName;
}
/*如果不传入第二个参数，那么将会被赋值为默认值。*/

/*注：可选参数和默认参数必须在参数列表的最后。*/

/*5、可变参数*/
function buildName3(firstName: string, ...restOfName: string[]) {    
    return firstName + " " + restOfName.join(" ");
}
var employeeName = buildName3("Joseph", "Samuel", "Lucas", "MacKinzie");
/*在参数名前面使用三个点表明该参数的个数是可变的，同样，也是必须在参数列表的最后。*/

/*6、lambda 和当前对象*/
/*在 JavaScript 中，this 关键字指代的是当前 function。那么我们就很有可能在定义方法时用错。参考下面：*/

var deck = {    
    suits: ["hearts", "spades", "clubs", "diamonds"],    
    cards: Array(52),    
    createCardPicker: function() {        
        return function() {            
            var pickedCard = Math.floor(Math.random() * 52);            
            var pickedSuit = Math.floor(pickedCard / 13);                        
            return {suit: this.suits[pickedSuit], card: pickedCard % 13};        
        }    
    }
}
var cardPicker = deck.createCardPicker();   // 返回函数
var pickedCard = cardPicker();      // 调用函数，此时this是windows对象
alert("card: " + pickedCard.card + " of " + pickedCard.suit);

/*
那么在调用 createCardPicker 方法的时候，我们将不会得到预期的结果，
因为 this 指的是当前 function，而不是 deck 对象。
为了解决这一点，TypeScript 引入 lambda 表示法
*/

var deck = {    
    suits: ["hearts", "spades", "clubs", "diamonds"],    
    cards: Array(52),    
    createCardPicker: function() {        
        // Notice: the line below is now a lambda, allowing us to capture 'this' earlier        
        return () => {           // 箭头函数，在函数创建时捕获this，绑定this为deck对象 
            var pickedCard = Math.floor(Math.random() * 52);            
            var pickedSuit = Math.floor(pickedCard / 13);                        
            return {suit: this.suits[pickedSuit], card: pickedCard % 13};        
        }    
    }
}
var cardPicker = deck.createCardPicker();   // 返回函数对象
var pickedCard = cardPicker();      // 调用函数
alert("card: " + pickedCard.card + " of " + pickedCard.suit);
/*那么现在 this，就指代 deck 对象了。*/

/*7、方法重载*/
/*因为 JavaScript 的语法，所以是不存在重载的。只要你在 JavaScript 中定义了一个方法，
那么传入多少个参数都是可以的。但是，从我们上面 TypeScript 的例子中，可以看出 TypeScript 
是会检查参数个数、类型是否匹配的。因此 TypeScript 中是有必要存在重载。*/

var suits = ["hearts", "spades", "clubs", "diamonds"];
function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {    
    // Check to see if we're working with an object/array    
    // if so, they gave us the deck and we'll pick the card    
    if (typeof x == "object") {        
        var pickedCard = Math.floor(Math.random() * x.length);        
        return pickedCard;    
    }    
    // Otherwise just let them pick the card    
    else if (typeof x == "number") {        
        var pickedSuit = Math.floor(x / 13);        
        return { suit: suits[pickedSuit], card: x % 13 };    
    }
}
var myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];
var pickedCard1 = myDeck[pickCard(myDeck)];
alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);
var pickedCard2 = pickCard(15);
alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);
/*上面代码是 TypeScript 官方的例子，其实可以看出，我们方法体都需要写在一个参数类型、
返回类型为 any 的方法中。所以看上去其实有点自欺欺人的意思。方法重载在 TypeScript 中的意义主要在于智能提示。*/


let myNewAdd: (x:number, y:number) => number = 
function(x:number, y:number):number{return x+y;}







